﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RobotBattle2.Runtime {
	public static class Value {
		public static decimal AsNumber(this object value) {
			if (value is IVariable)
				return ((IVariable)value).Value.AsNumber();
			return Convert.ToDecimal(value);
		}
		public static decimal AsNumber(this string value) {
			decimal result;
			if (Decimal.TryParse(value, out result))
				return result;
			return 0.0m;
		}

		public static string AsString(this object value) {
			if (value is IVariable)
				return ((IVariable)value).Value.AsString();
			else if (value is string)
				return (string)value;
			else
				return AsString(AsNumber(value));
		}
		public static string AsString(this decimal value) {
			return value.ToString();
		}

		public static bool AsBoolean(this object value) {
			if (value is IVariable)
				return ((IVariable)value).Value.AsBoolean();
			else if (value is string)
				return AsBoolean((string)value);
			else
				return AsBoolean(AsNumber(value));
		}
		public static bool AsBoolean(this string value) {
			return string.IsNullOrEmpty(value); // TODO: Is Value.AsBoolean(string) correct?
		}
		public static bool AsBoolean(this decimal value) {
			return value != 0.0m;
		}

		public static object AsValue(this object value) {
			if (value is IVariable)
				return ((IVariable)value).Value;
			else
				return value;
		}

		public static ValueTypeCode GetTypeCode(object value) {
			if (value == null) {
				return ValueTypeCode.Empty;
			} else if (value is IVariable) {
				return GetTypeCode(((IVariable)value).Value);
			}
			switch (Type.GetTypeCode(value.GetType())) {
				case TypeCode.Char:
				case TypeCode.String:
					return ValueTypeCode.String;
				case TypeCode.Boolean:
				case TypeCode.Byte:
				case TypeCode.Decimal:
				case TypeCode.Double:
				case TypeCode.Int16:
				case TypeCode.Int32:
				case TypeCode.Int64:
				case TypeCode.SByte:
				case TypeCode.Single:
				case TypeCode.UInt16:
				case TypeCode.UInt32:
				case TypeCode.UInt64:
					return ValueTypeCode.Number;
				default:
					throw new NotSupportedException();
			}
		}
	}
}
